home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Info-Mac 4
/
Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso
/
Development
/
Source
/
Telnet 2.6.1d1 4⁄26⁄94 Folder
/
source
/
network
/
netevent.c
< prev
next >
Wrap
Text File
|
1994-03-21
|
18KB
|
628 lines
/*
* netevent.c
* Originally by Gaige B. Paulsen
*****************************************************************
* NCSA Telnet for the Macintosh *
* *
* National Center for Supercomputing Applications *
* Software Development Group *
* 152 Computing Applications Building *
* 605 E. Springfield Ave. *
* Champaign, IL 61820 *
* *
* Copyright (c) 1986-1993, *
* Board of Trustees of the University of Illinois *
*****************************************************************
* Network event handler for NCSA Telnet for the Macintosh
*
* Called by:
* event.c
* maclook.c
*
* Revisions:
* 7/92 Telnet 2.6: added the 2 global structures, and cleaned up defines -- Scott Bulmahn
*/
#ifdef MPW
#pragma segment Network
#endif
#include <stdio.h>
#include <string.h>
#include "TelnetHeader.h"
#include "netevent.proto.h"
#include "InternalEvents.h"
#include "wind.h"
#include "mydnr.proto.h"
#include "bkgr.proto.h"
#include "maclook.proto.h"
#include "network.proto.h"
#include "menuseg.proto.h"
#include "rsmac.proto.h"
#include "vrrgmac.proto.h"
#include "tekrgmac.proto.h"
#include "vsdata.h"
#include "vskeys.h"
#include "translate.proto.h"
#include "debug.h"
#include "parse.proto.h"
#include "ftpbin.proto.h"
#include "Connections.proto.h"
#include "event.proto.h"
#include "telneterrors.h"
extern WindRec
*screens; /* The screen array from Maclook */
extern char *tempspot; /* 256 bytes for temp strings */
extern short scrn;
extern MenuHandle myMenus[];
short
FileInTransit,
blocksize, /* how large do we make the blocks when we read? */
gQueueError = 0, // Set to 1 if the queue fills up.
gQueueLength = 0, // Used to monitor queue length for debugging purposes.
gQueueInUse = 0; // Ditto.
QHdr gEventsQueue, gEventsFreeQueue;
unsigned char *readspace; /* main buffer space */
static void RangeError(short i);
void ftppasteText(short scrn);
#define PFTP 1
#define PRCP 2
#define PDATA 3
// Our "give time" routine
void Stask( void)
{
}
// Every time we open or close a network connection, we add or remove a few elements
// to/from the queue to assure that there will always be some free elements laying
// around. This allows us to avoid Dequeue'ing at interrupt time, which causes
// nasty mutex problems since we walk the queue in netgetevent at non-interrupt time.
void ChangeQueueLength(short delta)
{
internal_event *theEvent;
if (delta > 0)
while (delta != 0) {
theEvent = (internal_event *) NewPtrClear(sizeof(internal_event));
Enqueue((QElemPtr)theEvent, &gEventsFreeQueue);
gQueueLength++;
delta--;
}
else
while (delta != 0) {
theEvent = (internal_event *)gEventsFreeQueue.qHead;
Dequeue((QElemPtr)theEvent, &gEventsFreeQueue);
if (theEvent) DisposePtr((Ptr)theEvent);
gQueueLength--;
delta++;
}
}
/***********************************************************************/
/* netgetevent
* Retrieves the next event (and clears it) which matches bits in
* the given mask. Returns the event number or -1 on no event present.
* Also returns the exact class and the associated integer in reference
* parameters.
*/
short netgetevent(
// short mask,
short *class,
short *data1,
long *data2
)
{
internal_event *theEvent;
short event;
//#define QUEUE_STATS
#ifdef QUEUE_STATS
char qs[255];
static long timer = 0;
if (TickCount() - timer > 60*30) {
sprintf(qs, "QueueLength: %d, InUse: %d", gQueueLength, gQueueInUse);
timer = TickCount();
putln(qs);
}
#endif QUEUE_STATS
if (gQueueError) // Yikes, we actually ran out of queue elements!
DebugStr("\pOut of Queue Elements, please quit as quickly as possible!");
// Spin until we hit the end of the queue or if we Dequeue an element that is not
// already dequeued. If we don't do this check on Dequeue, someone else could come
// in and dequeue an element that we are about to dequeue. Thus, WHAM! we both have
// that queue element.
while ((theEvent = (internal_event *)gEventsQueue.qHead) != NULL) {
if (Dequeue((QElemPtr)theEvent, &gEventsQueue) == noErr)
break;
}
// while ((theEvent != NULL) && !(theEvent->eclass & mask))
// theEvent = (internal_event *)theEvent->qLink;
if (theEvent == NULL) return(-1);
// (void) Dequeue((QElemPtr)theEvent, &gEventsQueue);
*class = theEvent->eclass;
*data1 = theEvent->data1;
*data2 = theEvent->data2;
event = theEvent->event;
Enqueue((QElemPtr)theEvent, &gEventsFreeQueue);
gQueueInUse--;
return(event);
}
/***********************************************************************/
/* netputevent
* add an event to the queue.
* Will probably get the memory for the entry from the free list.
* Returns 0 if there was room, 1 if an event was lost.
*/
short netputevent
(
short class,
short what,
short data1,
long data2
)
{
internal_event *theEvent;
while ((theEvent = (internal_event *)gEventsFreeQueue.qHead) != NULL) {
if (Dequeue((QElemPtr)theEvent, &gEventsFreeQueue) == noErr)
break;
}
if (theEvent == NULL) {
gQueueError = 1; // Darn, we filled the queue, alert the user.
return(-1);
}
else
gQueueInUse++;
theEvent->qType = 0;
theEvent->eclass = class;
theEvent->event = what;
theEvent->data1 = data1;
theEvent->data2 = data2;
Enqueue((QElemPtr)theEvent, &gEventsQueue);
return(0);
}
/***************************************************************************/
/* netputuev
* put a unique event into the queue
* First searches the queue for like events
*/
short netputuev
(
short class,
short what,
short data1,
long data2
)
{
internal_event *theEvent = (internal_event *)gEventsQueue.qHead;
while((theEvent != NULL) && ((theEvent->eclass != class) || (theEvent->event != what)
|| (theEvent->data1 != data1) || (theEvent->data2 != data2)))
theEvent = (internal_event *)theEvent->qLink;
if (theEvent != NULL) return(0);
return(netputevent(class, what, data1, data2));
}
void RangeError(short i)
{
char temp[20];
sprintf(temp,"%d in %d", -i,TelInfo->numwindows);
putln(temp);
}
short WindByPort(short port)
{
short i=0;
while (i<TelInfo->numwindows &&
(screens[i].port != port ||
((screens[i].active != CNXN_ACTIVE) && (screens[i].active != CNXN_OPENING)))
) i++;
if (i>=TelInfo->numwindows) {
i = 0;
while ((i<TelInfo->numwindows) &&
((screens[i].ftpport != port) ||
((screens[i].active != CNXN_ACTIVE) && (screens[i].active != CNXN_OPENING)))
) i++;
if (i>=TelInfo->numwindows) { /* BYU */
putln("Can't find a window for the port # in WindByPort"); /* BYU */
RangeError(i); /* BYU */
if (i==0) i=999; /* BYU */
return(-i); /* BYU */
} /* BYU */
} /* BYU */
return(i);
}
void FlushNetwork(short scrn)
{
short throwsize,cnt=512;
if (blocksize < 512)
throwsize = 512;
else
throwsize = blocksize;
RSskip(screens[scrn].vs, 1); /* Don't do any output */
while (cnt>0) {
cnt = netread(screens[scrn].port,readspace,throwsize);
parse( &screens[scrn ], readspace, cnt);
}
RSskip(screens[scrn].vs, 0); /* Do output now */
SetPort( screens[scrn].wind);
InvalRect(&screens[scrn].wind->portRect); /* Don't forget to redraw */
}
void ftppasteText(short scrn) /* BYU */
{ /* BYU */
char *ascii; /* BYU */
/* BYU */
ascii = screens[scrn].outptr; /* BYU */
while ((screens[scrn].outlen > 0) && /* BYU */
(*ascii>31) && (*ascii <127)) { /* BYU */
parse( &screens[ scrn],(unsigned char *) ascii, 1); /* BYU LSC */
screens[scrn].kbbuf[ screens[scrn].kblen++ ] = *ascii; /* BYU */
screens[scrn].outlen--; /* BYU */
ascii++; /* BYU */
} /* BYU */
screens[scrn].outptr = ascii; /* BYU */
if (*ascii == '\015') { /* BYU */
parse( &screens[scrn],(unsigned char *) "\015\012",2); /* BYU LSC */
screens[scrn].kbbuf[ screens[scrn].kblen++ ] = 0; /* BYU */
ftppi(screens[scrn].kbbuf); /* BYU - ftp client */
screens[scrn].kblen=0; /* BYU */
} /* BYU */
while ((screens[scrn].outlen > 0) && /* BYU */
((*ascii<=31) || (*ascii >=127))) { /* BYU */
screens[scrn].outlen--; /* BYU */
screens[scrn].outptr++; /* BYU */
} /* BYU */
} /* BYU */
void pasteText(short scrn)
{
short amount;
if (!screens[scrn].outlen)
return;
if (netpush(screens[scrn].port) != 0) { /* BYU 2.4.16 - wait until not busy */
netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */
return; /* BYU 2.4.16 */
} /* BYU 2.4.16 */
if (screens[scrn].incount) { /* BYU 2.4.16 */
screens[scrn].incount = 0; /* BYU 2.4.16 */
screens[scrn].outcount = 0; /* BYU 2.4.16 */
netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */
return; /* BYU 2.4.16 */
} /* BYU 2.4.16 */
if (screens[scrn].outcount < 2) { /* BYU 2.4.16 */
screens[scrn].outcount++; /* BYU 2.4.16 */
netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */
return; /* BYU 2.4.16 */
}
if (netqlen(screens[scrn].port) > 0) { /* BYU 2.4.16 - wait until not full */
netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */
return; /* BYU 2.4.16 */
} /* BYU 2.4.16 */
if (screens[scrn].ftpstate != 0) /* BYU */
ftppasteText( scrn); /* BYU */
else { /* BYU */
if (!screens[scrn].pastemethod) { // Do this all at once?
amount = netwrite(screens[scrn].port, screens[scrn].outptr,
screens[scrn].outlen);
}
else { // Nope, do it in blocks
if (screens[scrn].pastesize <= screens[scrn].outlen)
amount = screens[scrn].pastesize;
else
amount = screens[scrn].outlen;
amount = netwrite(screens[scrn].port, screens[scrn].outptr, amount);
}
if (screens[scrn].echo) /* BYU */
parse( &screens[scrn],(unsigned char *) screens[scrn].outptr,amount); /* BYU LSC */
screens[scrn].outlen -= amount; /* BYU */
screens[scrn].outptr += (long) amount; /* BYU */
/* screens[scrn].outcount += amount; /* BYU LSC */
} /* BYU */
if ( screens[scrn].outlen <=0) {
screens[scrn].clientflags &= ~PASTE_IN_PROGRESS; /* BYU LSC */
HUnlock(screens[scrn].outhand);
DisposHandle(screens[scrn].outhand);
screens[scrn].outptr = (char *) 0L; /* BYU LSC */
screens[scrn].outhand = (char **) 0L; /* BYU LSC */
}
else
netputevent( USERCLASS, PASTELEFT, scrn,0);
}
void DoNetEvents(void)
{
short i, cnt;
long ftptime = 0;
short event, class, data1;
long data2, pos;
if ((event = netgetevent(&class, &data1, &data2)) < 0) return;
if ( (TickCount() - ftptime > 60*2) && FileInTransit) {
ftptime = TickCount();
Sftpstat(&pos); /* get transfer status */
if (pos <= 0)
ftpmess("FTP Status: transferring\015\012");
else
{
if (FileInTransit+2)
sprintf((char *) tempspot,"FTP Status: %ld bytes remaining.\015\012", pos); /* BYU LSC */
else
sprintf((char *) tempspot,"FTP Status: %ld bytes transferred.\015\012", pos); /* BYU LSC */
ftpmess((char *) tempspot); /* BYU LSC */
}
}
switch(class) {
case SCLASS:
switch (event) {
case FTPACT:
ftpd(0, data1);
break;
case CLOSEDONE: /* Used in the drivers */
netclose(data1);
break;
case CLOSEDONE+1: /* Used in the drivers */
netclose(data1);
break;
default:
break;
}
break;
case CONCLASS: /* Connection type event */
switch(GetPortType(data1)) {
case PFTP:
rftpd(event,data1); /* BYU 2.4.16 */
break;
case PDATA:
ftpd(event,data1);
break;
case UDATA: /* BYU */
userftpd(event,data1); /* BYU */
break; /* BYU */
default:
case CNXN_TYPE:
switch (event) {
case CONOPEN: /* connection opened or closed */
i=WindByPort(data1);
if (i<0) {
RangeError(i);
return;
}
/* BYU mod - This tests TRUE if it is the telnet port or the main ftp port */
if (data1 == screens[i].port) { /* BYU - is this Telnet? */
screens[ i].active= CNXN_ACTIVE;
RSshow( screens[i].vs); /* BYU */
SelectWindow(screens[i].wind); /* BYU */
/*
* Send Kerberos initial options.
*/
send_auth_opt(&screens[i]);
#if 0 /* BYU 2.4.20 */
if (screens[i].ftpstate != 0) /* BYU 2.4.20 - Only if not FTP */
userftpd(CONOPEN,data1); /* BYU */
#else /* BYU 2.4.20 */
if (screens[i].ftpstate == 0) { /* BYU - Only if not FTP */
netpush(screens[i].port); /* BYU */
netwrite(screens[i].port,"\377\375\001\377\375\003\377\374\43",9); /* BYU - Default telnet parms */
// IAC DOTEL ECHO IAC DOTEL SGA IAC WONTTEL XDISPLOC
} else { /* BYU */
userftpd(CONOPEN,data1); /* BYU */
} /* BYU */
#endif /* BYU 2.4.20 */
screens[i].Usga=1; /* BYU */
screens[i].echo = 1;
changeport(scrn,i); /* BYU */
SetMenuMarkToLiveForAGivenScreen(scrn); /* BYU */
DoTheMenuChecks(); /* BYU */
} else { /* BYU - not Telnet so must be FTP */
userftpd(CONOPEN,data1); /* BYU */
} /* BYU */
break;
case CONDATA: /* data arrived for me */
i=WindByPort(data1); /* BYU */
if (i<0) { RangeError(i); return; } /* BYU */
if (TelInfo->ScrlLock || !screens[i].enabled) /* BYU LSC */
netputuev( CONCLASS, CONDATA, data1,0);
else {
if (screens[i].ftpstate == 0)
{ /* normal session connection */
cnt = netread(data1,readspace,blocksize); /* BYU LSC */
parse( &screens[i], readspace, cnt); /* BYU LSC */
screens[i].incount += cnt; /* BYU LSC */
} /* BYU */
else { /* BYU */
userftpd(CONDATA,data1); /* BYU */
} /* BYU */
}
break;
case CONFAIL:
{
short i;
Str255 scratchPstring;
netclose( data1);
i= WindByPort(data1);
if (i<0) { RangeError(i); return; }
BlockMove((Ptr)screens[i].machine, (Ptr)scratchPstring, Length(screens[i].machine)+1);
PtoCstr(scratchPstring);
DoError(807 | NET_ERRORCLASS, LEVEL2, (char *)scratchPstring);
if (screens[i].active != CNXN_ACTIVE) destroyport(i); // JMB - 2.6
else removeport( i); // JMB - 2.6
}
break;
case CONCLOSE:
{
short i;
i= WindByPort(data1);
if (i<0) {
netclose( data1); /* We close again.... */
RangeError(i);
return;
}
/* BYU - This tests TRUE if it is the telnet port or the main ftp port */
if (data1 == screens[i].port) { /* BYU */
putln("Closing...."); /* BYU */
FlushNetwork(i); /* BYU */
netclose( screens[i].port); /* BYU */
removeport(i); /* BYU */
} /* BYU */
else { /* BYU */
userftpd(CONCLOSE,data1); /* BYU */
} /* BYU */
}
break;
default:
break;
}
break; /* Case port type = CNXN_TYPE */
// default:
// putln("Received CONCLASS event for port w/o valid type.");
// break;
}
break; /* CONCLASS */
case USERCLASS:
switch (event) {
case DOMAIN_DONE: // data1 = screen #, data2 = ptr to info structure
HandleDomainDoneMessage(data1, data2);
break;
case FTPBEGIN:
FileInTransit=data1;
ftptime=TickCount();
break;
case FTPEND:
ftpmess("FTP Transfer Concluding\015\012");
ftpmess("\015\012");
FileInTransit=0;
break;
case FTPCOPEN:
{
ip_addrbytes ftpinfo;
Str255 remoteMachineName;
if (gFTPServerPrefs->ResetMacBinary)
TelInfo->MacBinary = gFTPServerPrefs->UseMacBinaryII;
updateMenuChecks();
TelInfo->xferon=1;
updateCursor(1);
ftpmess("-----------------------------------------------------------------------------\015\012");
ftpmess("FTP server initiated from host: ");
ftpinfo.a.addr = Sftphost();
if (!TranslateIPtoDNSname(ftpinfo.a.addr, remoteMachineName))
sprintf((char *) &tempspot[4],"%u.%u.%u.%u\015\012",
(unsigned char)ftpinfo.a.byte[0],
(unsigned char)ftpinfo.a.byte[1],
(unsigned char)ftpinfo.a.byte[2],
(unsigned char)ftpinfo.a.byte[3]);
else {
PtoCstr(remoteMachineName);
sprintf((char *) &tempspot[4],"%s\015\012",remoteMachineName);
}
ftpmess((char *) &tempspot[4]); /* BYU LSC */
}
break;
case FTPCLOSE:
TelInfo->xferon=0;
updateCursor(1);
if (gFTPServerPrefs->ResetMacBinary)
TelInfo->MacBinary = gFTPServerPrefs->UseMacBinaryII;
updateMenuChecks();
ftpmess("FTP server ending session\015\012");
ftpmess("-----------------------------------------------------------------------------\015\012");
ftpmess("\015\012");
break;
case RG_REDRAW: /* RGredraw event */
if (VGalive(data1) && RGsupdate(data1))
TekEnable(data1);
break;
case PASTELEFT:
pasteText(data1);
break;
default:
break;
}
break; /* USERCLASS */
default:
break;
} /* switch (CLASS) */
} /* DoNetEvents */
/* setblocksize()
Make sure that we have space for the block of data that is to be read each
time the netread() is called. */
short setblocksize(short tosize)
{
blocksize = tosize; /* keep size of block */
if (tosize < 512) /* minimum buffer */
tosize = 512;
if (readspace)
DisposPtr((Ptr)readspace); /* free old block */
if (NULL == (readspace = (unsigned char *) NewPtrClear(tosize + 100))) /* BYU LSC */
return(-1);
return(0);
}